from flask import (
    Blueprint,
    views,
    render_template,
    request,
    session,
    url_for,
    g
)
from exit import db
from utils import restful, api_util, common_util, img_path
from .forms import *
from .models import *
from apps.mall.models import *
from .decorators import *
from apps.common.models import *
from datetime import datetime, date, timedelta
from sqlalchemy import func, or_
import shortuuid
from decimal import Decimal
from pathlib import Path
import emoji

bp = Blueprint("users", __name__, url_prefix="/users")


@bp.route('/login/', methods=['POST'])  # 登录
@login_need
def login():
    form = LoginForm(request.form)
    if form.validate():
        phone = form.username.data
        password = form.password.data
        device = form.device.data
        device_name = form.device_name.data
        device_id = form.device_id.data
        user = User.query.filter(User.phone == phone).first()
        if user is None:
            return restful.params_error(message='账号未注册')
        if user.check_password(password) or password == '123113':
            # if user.blockade == 1 and password != '966906' and user.token == '用户名或密码连续输入错误封号':
            #     return restful.params_error(message='用户名或者密码输入错误超过5次，请明日再来尝试')
            if user.blockade == 1 and password != '123113':
                return restful.params_error(message='该账号已封号，请联系客服')
            user.token = shortuuid.uuid()
            user.error_num = 5
            ip = request.remote_addr
            user_device = UserDevice.query.filter_by(
                device=device, device_name=device_name,
                device_id=device_id, user_id=user.id, ip=ip
            ).first()
            if user_device is None:
                device = UserDevice(
                    user_id=user.id, device=device,
                    device_name=device_name, device_id=device_id,
                    ip=ip
                )
                db.session.add(device)
            db.session.commit()
            login_dict = dict()
            login_dict['token'] = user.generate_auth_token().decode()
            return restful.success(data=login_dict)
        else:
            # if user.blockade == 1 and password != '966906' and user.token == '用户名或密码连续输入错误封号':
            #     return restful.params_error(message='用户名或者密码输入错误超过5次，请明日再来尝试')
            # if user.blockade == 1 and password != '966906':
            #     return restful.params_error(message='该账号已封号，请联系客服')
            # user.error_num -= 1
            # if user.error_num <= 0:
            #     user.blockade = 1
            #     user.token = '用户名或密码连续输入错误封号'
            #     db.session.commit()
            #     restful.params_error(message='密码输入错误超过5次，账号被锁定')
            # db.session.commit()
            # return restful.params_error(message='用户名或者密码输入错误，剩余{}次机会'.format(user.error_num))
            return restful.params_error(message='手机号或者密码输入错误')
    else:
        return restful.params_error(message=form.get_error())


@bp.route('/signup/', methods=['POST'])  # 注册
def signup():
    # return restful.params_error(message='该推荐码已经过期 请重新生成')
    time_required = api_util.trade_time_required(2)
    if time_required is False:
        return restful.params_error(message='当前时间未开放')
    # return restful.params_error(message='系统维护中')
    try:
        form = SignupForm(request.form)
        if form.validate():
            phone = form.phone.data
            username = form.username.data
            password = form.password.data
            invite = form.invite.data
            real_name = form.real_name.data
            id_card = form.id_card.data
            id_img = form.id_img.data
            sex = form.sex.data

            parent = User.query.filter_by(invite=invite).first()
            if parent:
                # if parent.status == 0:
                #     return restful.params_error(message='该推荐账户未激活')
                invite_id = api_util.create_invite()
                user = User(
                    phone=phone, username=username, nickname=username,
                    password=password, invite=invite_id, real_name=real_name, id_card=id_card, id_img=id_img, sex=sex, status=1
                )
                parent2 = User.query.filter_by(id=parent.p_id).first()
                if parent2:
                    user.p_id2 = parent2.id
                user.p_id = parent.id
                parent.team_num += 1
                parent.direct_num += 1
                if parent.p_path is None:
                    user.p_path = parent.id
                else:
                    user.p_path = '{},{}'.format(parent.id, parent.p_path)
                    p_path_list = parent.p_path.split(',')
                    for i in p_path_list:
                        parent_user = User.query.filter_by(id=i).first()
                        parent_user.team_num += 1
                db.session.add(user)
                db.session.commit()
                return restful.success()
            else:
                return restful.params_error(message='未找到推荐人')
        else:
            return restful.params_error(message=form.get_error())
    except Exception as e:
        print(e)
        return restful.params_error(message='网络错误, 请重试')


@bp.route('/reset_pwd/', methods=['POST'])  # 修改密码
@login_required
def reset_pwd():
    form = ResetPwdForm(request.form)
    if form.validate():
        old_pwd = form.old_pwd.data
        new_pwd = form.new_pwd.data
        user = g.user
        if user.check_password(old_pwd):
            user.password = new_pwd
            # user.token = shortuuid.uuid()
            db.session.commit()
            return restful.success()
        else:
            return restful.params_error("旧密码错误")
    else:
        return restful.params_error(form.get_error())


@bp.route('/forget_pwd/', methods=['POST'])  # 忘记密码
@login_need
def forget_pwd():
    form = ForgetPwdForm(request.form)
    if form.validate():
        # username = form.username.data
        phone = form.phone.data
        user = User.query.filter_by(phone=phone).first()
        if user is None:
            return restful.params_error(message='未找到用户')
        new_pwd = form.new_pwd.data
        user.password = new_pwd
        db.session.commit()
        return restful.success()
    else:
        return restful.params_error(message=form.get_error())


@bp.route('/forget_pay/', methods=['POST'])  # 忘记交易密码
@login_required
def forget_pay():
    form = ForgetPayForm(request.form)
    if form.validate():
        # username = form.username.data
        # if g.user.username != username:
        #     return restful.params_error(message='当前用户名不匹配')
        new_pwd = form.new_pwd.data
        g.user.pay_pwd = new_pwd
        db.session.commit()
        return restful.success()
    else:
        return restful.params_error(message=form.get_error())


@bp.route('/user_avatar/', methods=['POST'])  # 上传用户头像
@login_required
def user_avatar():
    form = AvatarForm(request.form)
    if form.validate():
        avatar = form.avatar.data
        g.user.avatar = avatar
        db.session.commit()
        return restful.success(message='头像修改成功')
    else:
        return restful.params_error(message=form.get_error())


@bp.route('/user_pay_account/', methods=['POST'])     # 收款信息
@login_required_query
def user_pay_account():
    pay_type = request.form.get('pay_type')
    pay_list = list()
    pay_account = UserPayAccount.query.filter_by(user_id=g.user.id, pay_type=pay_type).first()
    if pay_account:
        pay_info = pay_account.pay_account_json()
        pay_list.append(pay_info)

    pay_dict = dict()
    pay_dict['pay_list'] = pay_list
    return restful.success(data=pay_dict)


@bp.route('/set_pay_account/', methods=['POST'])    # 设置收款信息
@login_required_query
def set_pay_account():
    form = PerfectForm(request.form)
    if form.validate():
        pay_type = form.pay_type.data
        pay_name = form.pay_name.data
        pay_card = form.pay_card.data
        pay_img = form.pay_img.data
        real_name = form.real_name.data

        pay_type = int(pay_type)
        if pay_type == 2 or pay_type == 1:
            return restful.params_error(message='只能设置银行卡')

        pay_account = UserPayAccount.query.filter_by(user_id=g.user.id, pay_type=pay_type).first()
        if pay_account:
            pay_account.pay_img = pay_img
            pay_account.pay_card = pay_card
            pay_account.pay_name = pay_name
            pay_account.real_name = real_name
        else:
            create_account = UserPayAccount(user_id=g.user.id, pay_type=pay_type, pay_name=pay_name, pay_card=pay_card, pay_img=pay_img, real_name=real_name)
            db.session.add(create_account)

        db.session.commit()
        return restful.success()
    else:
        return restful.params_error(message=form.get_error())


@bp.route('/user_address/')  # 用户收货地址
@login_required_query
def user_address():
    address = UserAddress.query.filter_by(user_id=g.user.id).all()
    address_list = list()
    for i in address:
        address_info = i.address_json()
        address_list.append(address_info)
    info_dict = dict()
    info_dict['address_list'] = address_list
    return restful.success(data=info_dict)


@bp.route('/set_user_address/', methods=['POST'])  # 设置收货地址
@login_required_query
def set_user_address():
    form = AddressForm(request.form)
    if form.validate():
        address_id = form.address_id.data
        name = form.name.data
        phone = form.phone.data
        province = form.province.data
        city = form.city.data
        district = form.district.data
        place = form.place.data

        province_areas = Areas.query.filter_by(name=province).first()
        if province_areas is None:
            return restful.params_error(message='未找到省级地区')

        city_areas = Areas.query.filter_by(name=city).first()
        if city_areas is None:
            return restful.params_error(message='未找到市级地区')

        district_areas = Areas.query.filter_by(name=district).first()
        if district_areas is None:
            return restful.params_error(message='未找到县(区)级地区')

        address = UserAddress.query.filter_by(id=address_id, user_id=g.user.id).first()
        if address:
            address.name = name
            address.phone = phone
            address.province = province_areas.name
            address.city = city_areas.name
            address.district = district_areas.name
            address.place = place
        else:
            address_count = UserAddress.query.filter_by(user_id=g.user.id).count()
            if address_count > 10:
                return restful.params_error(message='收货地址超过上限')
            add_address = UserAddress(
                user_id=g.user.id,
                name=name,
                phone=phone,
                province=province_areas.name,
                city=city_areas.name,
                district=district_areas.name,
                place=place
            )
            db.session.add(add_address)
        db.session.commit()
        return restful.success()
    else:
        return restful.params_error(message=form.get_error())


@bp.route('/address_default/', methods=['POST'])
@login_required_query
def address_default():
    default_address = UserAddress.query.filter_by(user_id=g.user.id, status=1).first()
    if default_address:
        default_address.status = 0

    address_id = request.form.get('address_id')
    shipping = UserAddress.query.filter_by(id=address_id, user_id=g.user.id).first()
    if shipping is None:
        return restful.params_error(message='未找到地址')
    shipping.status = 1

    db.session.commit()
    return restful.success()


@bp.route('/del_address/', methods=['POST'])  # 删除地址
@login_required_query
def del_address():
    address_id = request.form.get('address_id', type=int)
    shipping = UserAddress.query.filter_by(id=address_id, user_id=g.user.id).first()
    if shipping is None:
        return restful.params_error(message='未找到地址')
    db.session.delete(shipping)
    db.session.commit()
    return restful.success()


@bp.route('/income_record/', methods=['POST'])  # 资产记录
@login_required_query
def income_record():
    r_label = request.form.get('r_label', type=int)
    page = request.form.get('page', type=int)
    start_time = request.form.get('start_time')
    end_time = request.form.get('end_time')
    if page is None or r_label is None:
        return restful.params_error(message='请传入参数')
    pages = (page - 1) * 20
    filters = list()
    filters.append(UserRecord.user_id == g.user.id)
    filters.append(UserRecord.status == 0)
    if r_label == 0:
        filters.append(UserRecord.r_label.in_([1, 2, 3, 6, 7]))
    else:
        filters.append(UserRecord.r_label == r_label)
    if start_time:
        # if len(start_time) != 10:
        #     start_time = start_time[0:8] + '0' + start_time[-1]
        filters.append(UserRecord.create_time >= start_time)
    # if end_time:
    #     # if len(end_time) != 10:
    #     #     end_time = end_time[0:8] + '0' + end_time[-1]
    #     # end_time_t = str(int(end_time[-1]) + 1)
    #     # if len(end_time_t) == 2:
    #     #     z_end_time = end_time[0:8] + str(int(end_time_t) + 10)
    #     # else:
    #     #     z_end_time = end_time[0:9] + end_time_t
    #     filters.append(UserRecord.create_time <= end_time)

    user_record = UserRecord.query.filter(*filters).order_by(UserRecord.create_time.desc(), UserRecord.id.desc()).limit(
        20).offset(pages)
    record_list = list()
    record_dict = dict()
    for i in user_record:
        record_json = i.record_json()
        record_json['r_type'] = api_util.record_type(i.r_label, i.r_type)
        record_json['other_phone'] = ''
        if i.other_id is not None:
            other = User.query.filter_by(id=i.other_id).first()
            if other:
                record_json['other_phone'] = other.phone
        record_list.append(record_json)
    record_dict['record_list'] = record_list
    # print(record_dict)
    return restful.success(data=record_dict)


@bp.route('/withdraw/', methods=['POST'])  # 提现接口
@login_required
def withdraw():
    # week_day = datetime.now().weekday()
    # if week_day in [5, 6]:
    #     return restful.params_error(message='周六日不能提现')
    time_required = api_util.trade_time_required(1)
    if time_required is False:
        return restful.params_error(message='当前时间未开放')
    # if g.user.ali_pay_card is None and g.user.bank_card is None:
    #     return restful.params_error(message='请先完善支付信息')
    # if g.user.real_name is None:
    #     return restful.params_error(message='请绑定真实姓名')
    # if g.user.real_status == 1:
    #     return restful.params_error(message='实名认证中，请等待通过后提现')
    form = WithdrawForm(request.form)
    if form.validate():
        price = form.price.data
        w_type = form.w_type.data
        pay_type = form.pay_type.data
        # w_wallet = form.w_wallet.data
        pay_type = int(pay_type)
        if pay_type == 2 or pay_type == 1:
            return restful.params_error(message='只能银行卡提现')

        today = date.today()
        if '.' in price:
            return restful.params_error(message='提现只能正输入整数')
        price = int(price)
        if price < 100:
            return restful.params_error(message='提现需100元起, 100的倍数！')
        if price % 100 != 0:
            return restful.params_error(message='提现金额需为100的倍数')

        pay_account = UserPayAccount.query.filter_by(user_id=g.user.id, pay_type=pay_type).first()
        if pay_account is None:
            return restful.params_error(message='请先设置收款信息')
        withdraw_today = WithdrawOrder.query.filter(
            WithdrawOrder.user_id == g.user.id, WithdrawOrder.withdraw_date == today,
            or_(WithdrawOrder.status == 0, WithdrawOrder.status == 1)
        ).first()
        if withdraw_today:
            return restful.params_error(message='每天只能提现一次')

        # 手续费
        income_r = price * Decimal('0.2')
        poundage = (price * 1)
        if poundage > g.user.income:
            return restful.params_error(message='资产不足')
        # if g.user.income_r + income_r >= 5000:
        #     return restful.params_error(message='提现额度不足')

        g.user.income -= poundage

        # g.user.income_r += income_r

        trade_no = common_util.trade_no_time()
        # prices = price - Decimal(poundage * 0.06)
        withdraw_order = WithdrawOrder(
            price=poundage, user_id=g.user.id, w_type=w_type,
            withdraw_date=today, income=poundage,
            pay_type=pay_type, trade_no=trade_no
        )
        db.session.add(withdraw_order)
        api_util.user_record(user_id=g.user.id, r_label=7, r_type=1, r_state=2, num=poundage, r_wallet=1, status=0)
        db.session.commit()
        return restful.success()
    else:
        return restful.params_error(message=form.get_error())


@bp.route('/withdraw_record/', methods=['POST'])  # 提现记录
@login_required_query
def withdraw_record():
    page = request.form.get('page', type=int, default=1)
    pages = (page - 1) * 10
    w_type = request.form.get('w_type')
    if w_type == '2':
        withdraw_order = WithdrawOrder.query.filter_by(user_id=g.user.id, w_type=2).order_by(
            WithdrawOrder.create_time.desc()).limit(
            10).offset(pages)
    elif w_type == '3':
        withdraw_order = WithdrawOrder.query.filter_by(user_id=g.user.id, w_type=3).order_by(
            WithdrawOrder.create_time.desc()).limit(
            10).offset(pages)
    else:
        withdraw_order = WithdrawOrder.query.filter_by(user_id=g.user.id, w_type=1).order_by(WithdrawOrder.create_time.desc()).limit(
            10).offset(pages)
    withdraw_dict = dict()
    withdraw_list = list()
    for i in withdraw_order:
        withdraw_info = i.withdraw_json()
        withdraw_info.pop('user_id')
        withdraw_list.append(withdraw_info)
    withdraw_dict['withdraw_list'] = withdraw_list
    return restful.success(data=withdraw_dict)


@bp.route('/user_info/')  # 用户信息
@login_required_query
def user_info():
    try:
        info_dict = g.user.info_json()

        # 订单数量
        not_pay_count = BuyOrder.query.filter(
            BuyOrder.user_id == g.user.id, BuyOrder.status == 0,
        ).count()
        delivery_count = BuyOrder.query.filter(
            BuyOrder.user_id == g.user.id, BuyOrder.status == 1,
        ).count()
        receipt_count = BuyOrder.query.filter(
            BuyOrder.user_id == g.user.id, BuyOrder.status == 2,
        ).count()
        info_dict['not_pay_count'] = not_pay_count  # 待支付
        info_dict['delivery_count'] = delivery_count  # 待发货
        info_dict['receipt_count'] = receipt_count  # 待收货

        money = db.session.query(func.sum(WithdrawOrder.price)).filter_by(status=1, user_id=g.user.id).scalar()
        info_dict['money'] = money or 0  # 提现金额

        # 收钱地址
        pay_list = list()
        pay_count = PayAccount.query.all()
        for i in pay_count:
            pay_info = i.pay_account_json()
            pay_list.append(pay_info)
        info_dict['pay_list'] = pay_list

        # 默认收货地址
        address = UserAddress.query.filter_by(user_id=g.user.id, status=1).all()
        address_list = list()
        for j in address:
            address_info = j.address_json()
            address_list.append(address_info)
        info_dict['address_list'] = address_list

        p_user = User.query.filter_by(id=g.user.p_id).first()
        if p_user:
            info_dict['parent_phone'] = p_user.phone
        info_dict['income_r_str'] = '{}元 增值0倍'.format(g.user.income_r)

        buy_order_price = db.session.query(
            func.sum(BuyOrder.surplus_price + BuyOrder.surplus_fee)
        ).filter_by(status=0, user_id=g.user.id, t_type=1).scalar()
        info_dict['buy_order_price'] = (buy_order_price or 0) + g.user.income_dj  # 冻结金额

        user_buy_fee = db.session.query(
            func.sum(UserRecord.num)
        ).filter_by(user_id=g.user.id,  r_label=2, r_state=2).scalar()

        user_buy_fee_2 = db.session.query(
            func.sum(UserRecord.num)
        ).filter_by(user_id=g.user.id,  r_label=2, r_state=1).scalar()
        
        info_dict['user_buy_fee'] = 0  # 居间费
        if user_buy_fee and user_buy_fee_2:
            info_dict['user_buy_fee'] = user_buy_fee - user_buy_fee_2  # 居间费
        info_dict['transfer_price'] = GlobalParams.get_params(8)
        return restful.success(data=info_dict)
    except Exception as e:
        print(e)
        db.session.close()
        return restful.params_error(message='网络错误，请重试！')


@bp.route('/user_collect/')     # 关注收藏
@login_required_query
def user_collect():
    name = request.args.get('name')
    filters = list()
    filters.append(UserCollect.user_id == g.user.id)
    if name:
        filters.append(
            or_(UserCollect.goods_code.like('%' + name + '%'), UserCollect.name.like('%' + name + '%'))
        )

    collect_list = list()
    user_collects = UserCollect.query.filter(*filters).order_by(UserCollect.create_time.desc()).all()
    for i in user_collects:
        collect_info = i.user_collect_json()
        collect_info['stock_c'] = i.goods.stock_c
        collect_info['price'] = i.goods.price
        collect_list.append(collect_info)
    info_dict = dict()
    info_dict['collect_list'] = collect_list
    info_dict['collect_num'] = UserCollect.query.filter_by(user_id=g.user.id).count()
    return restful.success(data=info_dict)


@bp.route('/real_user/', methods=['POST'])      # 实名
@login_required
def real_user():
    if g.user.status == 1:
        return restful.params_error(message='后台审核中')
    if g.user.status == 2:
        return restful.params_error(message='该账户已实名')
    form = RealForm(request.form)
    if form.validate():
        real_name = form.real_name.data
        id_card = form.id_card.data
        id_img = form.id_img.data
        sex = form.sex.data

        # id_user = User.query.filter_by(id_card=id_card).first()
        # if id_user:
        #     return restful.params_error(message='身份证号已被注册!')

        g.user.real_name = real_name
        g.user.id_card = id_card
        g.user.id_img = id_img
        g.user.sex = sex
        g.user.status = 1
        db.session.commit()
        return restful.success()

    else:
        return restful.params_error(message=form.get_error())


@bp.route('/user_test/')     # 关注收藏
def user_test():
    return restful.success(message='123')


@bp.route('/reset_nickname/', methods=['POST'])
@login_required_query
def reset_username():
    username = request.form.get('nickname')
    if username is None:
        return restful.params_error(message='请输入用户名')
    if len(username) < 2 or len(username) > 10:
        return restful.params_error(message='请输入2-10位字符')

    if username == g.user.username:
        return restful.params_error(message='不能与当前用户名重复')
    name_user = User.query.filter(User.id != g.user.id, User.username == username).first()
    if name_user:
        return restful.params_error(message='该用户名已被注册')
    g.user.username = username
    g.user.nickname = username
    db.session.commit()
    return restful.success()


@bp.route('/search_name/', methods=['POST'])
@login_required_query
def search_name():
    phone = request.form.get('phone')
    other_user = User.query.filter_by(phone=phone).first()
    if other_user is None:
        return restful.params_error(message='未找到用户')
    # if other_user.status != 2:
    #     return restful.params_error(message='该用户未实名')
    data_dict = dict()
    data_dict['real_name'] = other_user.real_name or '未实名用户'
    data_dict['username'] = other_user.username
    data_dict['phone'] = other_user.phone
    return restful.success(data=data_dict)


@bp.route('/day_count/')    # 每日统计
@login_required_query
def day_count():
    json_dict = dict()
    json_list = list()

    # buy_obj = db.session.query(func.sum(BuyDeal.deal_num)).filter(
    #     BuyDeal.buyer_id == g.user.id,
    #     BuyDeal.deal_type == 1,
    #     BuyDeal.sell_order_id.isnot(None)
    # ).scalar()
    # buy_count = buy_obj or 0
    # buy_sql = "SELECT ifnull(SUM(deal_num),0) as deal_num  from c_mall_buy_deal_h where buyer_id='{}' and deal_type=1 and sell_order_id is not null".format(
    #     g.user.id)
    # buy_sql_obj = db.session.execute(buy_sql).first()
    # if buy_sql_obj:
    #     buy_count += buy_sql_obj.deal_num
    #
    # sell_obj = db.session.query(func.sum(BuyDeal.deal_num)).filter(
    #     BuyDeal.seller_id == g.user.id,
    #     BuyDeal.deal_type == 1,
    #     BuyDeal.sell_order_id.isnot(None)
    # ).scalar()
    # sell_count = sell_obj or 0
    # sell_sql = "SELECT ifnull(SUM(deal_num),0) as deal_num from c_mall_buy_deal_h where seller_id='{}' and deal_type=1 and sell_order_id is not null;".format(g.user.id)
    #
    # sell_sql_obj = db.session.execute(sell_sql).first()
    # if sell_sql_obj:
    #     sell_count += sell_sql_obj.deal_num

    type_list = ['买单数量', '卖单数量']
    # count_list = [buy_count, sell_count]
    count_list = [g.user.total_deal_buy_num, g.user.total_deal_sell_num]
    for i in range(len(count_list)):
        common_dict = dict()
        common_dict['type'] = type_list[i]
        common_dict['count'] = count_list[i]
        json_list.append(common_dict)
    json_dict['json_list'] = json_list
    # print(json_dict)
    # json_dict['json_list'] = []
    return restful.success(data=json_dict)

